﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Diagnostics;
using LIUS.Beta.FileSystem.PathFileSuffix;

namespace Kopain2
{

    /// <summary>This class contains the repository.  This is like files and such.  The Concept.
    /// </summary>
    internal class Repository
    {

#region	Private properties.

        private KopainConcept.Concept _concept;

        //private KopainDocumentTree _documentTree;

#endregion	//	Private properties.

#region	Public properties.

        internal KopainConcept.Concept Concept { get { return _concept; } }

        //internal KopainDocumentTree DocumentList { get { return _documentTree; } }

#endregion	//	Public properties.

#region	Public methods.

        /// <summary>This method creates a new empty Concept.  Not tested.  See under the menu:file:new how it maybe should be done.
        /// </summary>
        internal static KopainConcept.Concept CreateNew()
            //_documentList = new KopainDocumentTree();
            //PopulateNodelist(null, _documentList, treeDocument.ChildNodes);
        {
            // Create the new file name.
            FilenameSuffix newFilenameAndSuffix = CreateNewFilenameAndSuffix();
            var path = new LIUS.Beta.FileSystem.PathFileSuffix.Path(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + PathFilenameSuffixBase.Backslash, HandleValue.Wash);
            var pathFilenameSuffix = new PathFilenameSuffix(path, newFilenameAndSuffix);
            return CreateNew(pathFilenameSuffix);
        }

        /// <summary>This method creates a new empty Concept with a name&path.
        /// </summary>
        /// <param name="pathAndFilenameAndSuffix"></param>
        /// <returns></returns>
        internal static KopainConcept.Concept CreateNew(PathFilenameSuffix pathAndFilenameAndSuffix)
        {
            return KopainConcept.Concept.CreateNew(pathAndFilenameAndSuffix);
            //Open(pathAndFilenameAndSuffix);
        }

        /// <summary>This method loads the Repository with a Concept.
        /// </summary>
        /// <param name="pathFilenameSuffix"></param>
        internal void Load( LIUS.Beta.FileSystem.PathFileSuffix.PathFilenameSuffix pathFilenameSuffix)
        {
            Debug.Fail("Not tested.");
            //string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            //XmlDocument treeDocument = LIUS.Beta.FileSystem.Directory.FilesAsXml(path);

            //_documentList = new KopainDocumentTree();
            //PopulateNodelist(null, _documentList, treeDocument.ChildNodes);
        }

        /// <summary>This method opens and populates a Concept with the contents of an already persisted (this means: is on harddisk) Concept.
        /// </summary>
        /// <param name="pathFilenameSuffix"></param>
        internal void Open(PathFilenameSuffix pathFilenameSuffix)
        {
            _concept = KopainConcept.Concept.Open(pathFilenameSuffix);
            
            // This old code reads the contents of the disc and creates a Concept out of it.  Might be used in the future like for Import.
            //_documentList = new KopainDocumentTree();
            //XmlDocument treeDocument = LIUS.Prospect.FileSystem.Directory.FilesAsXml(path);
            //PopulateNodelist(null, _documentList, treeDocument.ChildNodes);

            //_documentTree = PopulateNodeTree(_concept.NoteList);
        }

        /// <summary>This method persists the Repository.
        /// </summary>
        internal void Save()
        {
            _concept.Save();
        }

#endregion	//	Public methods.

#region	Private methods.

        /// <summary>This method returns a new filename.  It should be updated to take the path into consideration and not suggest a filename of a file that already exists.
        /// </summary>
        /// <returns></returns>
        private static LIUS.Beta.FileSystem.PathFileSuffix.FilenameSuffix CreateNewFilenameAndSuffix()
        {
            //TODO:Create a unique new filename.
            return new FilenameSuffix("NewFile", KopainConcept.Constant.DefaultSuffixName, LIUS.Beta.FileSystem.PathFileSuffix.HandleValue.RequireExact, LIUS.Beta.FileSystem.PathFileSuffix.AllowPeriod.Yes, LIUS.Beta.FileSystem.PathFileSuffix.RequireSuffix.Yes);
        }

        /// <summary>This method takes whatever Notes are in the Concept and creates a KopainDocumentTree out of it.
        /// There is something wrong here - it should create a tree and not a list.
        /// </summary>
        /// <param name="noteList"></param>
        /// <returns></returns>
        private static KopainDocumentTree PopulateNodeTree(List<KopainConcept.Concept.Note> noteList)
        {
            var ret = new KopainDocumentTree();
            foreach (var note in noteList)
            {
                // The null below should be a parent KopainDocument.  Where do we get this?
                ret.Add(KopainDocument.CreateFile(null, note.ID, note.Title, note.FilenameSuffix));
            }
            return ret;
        }

        private static void PopulateNodelist(KopainDocument parent, KopainDocumentTree nodeList, XmlNodeList xmlNodeList)
        {
            foreach (XmlElement element in xmlNodeList)
            {
                KopainDocument newNode = null;
                switch (element.Name)
                {
                    case LIUS.Beta.FileSystem.Directory.Element.DirectoryName:
                        newNode = KopainDocument.CreateDirectory(
                            parent, 
                            Guid.NewGuid(), 
                            element.Attributes[LIUS.Beta.FileSystem.Directory.Attribute.NameName].Value,
                            new PathFilenameSuffix( element.Attributes[LIUS.Beta.FileSystem.Directory.Attribute.PathName].Value, HandleValue.RequireExact ).Path, 
                            true);
                        break;

                    case LIUS.Beta.FileSystem.Directory.Element.FileName:
                        string name = element.Attributes[LIUS.Beta.FileSystem.Directory.Attribute.NameName].Value;
                        if (name == "kopain.xml.txt")
                        {
                            parent.Expanded = false;
                        }
                        else
                        {
                            newNode = KopainDocument.CreateFile(parent, Guid.NewGuid(), name, new FilenameSuffix(name, AllowPeriod.Yes, RequireSuffix.No));   // I am not sure this coded is totally correct.
                        }
                        break;

                    case LIUS.Beta.FileSystem.Directory.Element.RootName:
                        PopulateNodelist(parent, nodeList, element.ChildNodes);
                        break;

                    default:
                        Debug.Fail("Invalid path");
                        break;
                }
                if (null != newNode)
                {
                    nodeList.Add(newNode);
                    newNode.Children = new KopainDocumentTree();
                    PopulateNodelist(newNode, newNode.Children, element.ChildNodes);
                }
            }
        }

#endregion	//	Private methods.

    }

}
